#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <zmq.h>

#include <iostream>
#include <thread>

void server(void) {
  //  Socket to talk to clients
  void *context = zmq_ctx_new();
  void *responder = zmq_socket(context, ZMQ_REP);
  int rc = zmq_bind(responder, "tcp://*:5555");
  assert(rc == 0);
  while (1) {
    char buffer[10];
    zmq_recv(responder, buffer, 10, 0);
    std::cout << "Server Received:" << buffer << std::endl;
    sleep(1);  //  Do some 'work'
    // zmq_send(responder, "World", 5, 0);
    // std::cout << "Server send World" << std::endl;
  }
}

void client(void) {
  std::cout << "Connecting to hello world server…" << std::endl;
  void *context = zmq_ctx_new();
  void *requester = zmq_socket(context, ZMQ_REQ);
  zmq_connect(requester, "tcp://localhost:5555");

  int request_nbr;
  for (request_nbr = 0; request_nbr != 10; request_nbr++) {
    char buffer[10];
    std::cout << "client Send Hello" << std::endl;
    zmq_send(requester, "Hello", 5, 0);
    zmq_recv(requester, buffer, 10, 0);
    std::cout << "client Received: " << buffer << std::endl;
  }
  zmq_close(requester);
  zmq_ctx_destroy(context);
}

int main(int argc, char **argv) {
  std::thread server_thread = std::thread(server);
  std::thread client_thread = std::thread(client);

  if (server_thread.joinable()) {
    server_thread.join();
  }

  if (client_thread.joinable()) {
    client_thread.join();
  }
  return 0;
}